<?php

namespace app\admin\controller\yungift\fund;

use addons\yungift\library\Super;
use addons\yungift\model\Activity;
use addons\yungift\model\FundRecord;
use addons\yungift\model\Group;
use addons\yungift\model\Member;
use addons\yungift\model\Norepeat;
use \app\admin\model\yungift\FundUser;
use app\common\controller\Backend;
use fast\Random;
use think\Db;
use think\Exception;
use think\exception\PDOException;
use think\Model;

/**
 * 礼币 - 用户
 */
class User extends Backend
{
    /**
     * @var FundUser
     */
    protected $model;

    // 联表查询，解决字段冲突
    protected $relationSearch = true;

    public function _initialize()
    {
        parent::_initialize();
        $this->model = new FundUser();

        $this->view->assign('statusList', $this->model::getStatusList());
        $this->assignconfig('statusList', $this->model::getStatusList());
    }

    /**
     * 查看
     */
    public function index()
    {
        $activityId = $this->request->request('activity_id');
        if (! $activity = Activity::get($activityId)) {
            $this->error(__('活动不存在'));
        }
        if ($this->request->isAjax()) {
            // 重载查询条件
            $filter = $this->request->get('filter');
            $op = $this->request->get('op');
            list($filter, $op) = $this->formatFilterOp($filter, $op);
            $this->request->get(['filter' => $filter, 'op' => $op]);

            // 通用查询条件
            $this->model = new Member();
            list($where, $sort, $order, $offset, $limit) = $this->buildparams();
            $query = $this->model->alias('member')->with(['group_data'])
                ->field('*, member.id id, fund_user.id fid')
                ->join([FundUser::getTableName() => 'fund_user'],
                    'fund_user.member_id=member.id and fund_user.activity_id=' . $activityId . ' and fund_user.deleted_at is null',
                    'LEFT')
                ->where($where)
                ->where('member.deleted_at is null');
            if ($activity->group_ids) {
                $query->where('member.group_id', 'in', explode(',', $activity->group_ids));
            }
            $list = $query->order($sort, $order)->limit($offset, $limit)->paginate($limit);
            foreach ($list as $item) {
                $item->append(['group_text']);
            }
            $result = array(
                'total' => $list->total(),
                'rows'  => $list->items(),
            );

            return json($result);
        }

        // 活动ID
        $this->view->assign('activity', $activity);
        $this->assignconfig('activity', $activity);
        $this->view->assign('activity_id', $activityId);
        $this->assignconfig('activity_id', $activityId);

        // 分组列表
        $groupList = Group::getTreeList();
        $groupMap = ['0' => '未分组'];
        foreach ($groupList as $item) {
            $groupMap[$item['id']] = $item['name'];
        }
        if ($activity->group_ids) {
            $groupIds = explode(',', $activity->group_ids);
            foreach ($groupMap as $key => $value) {
                if (! in_array($key, $groupIds)) {
                    unset($groupMap[$key]);
                }
            }
        }
        $this->view->assign('groupMap', $groupMap);
        $this->assignconfig('groupMap', $groupMap);

        // 账户状态
        $stateList = ['-1' => '未激活'] + $this->model::getStatusList();
        $this->view->assign('stateList', $stateList);
        $this->assignconfig('stateList', $stateList);

        return $this->view->fetch();
    }

    /**
     * 格式化查询条件
     *
     * @param $filter
     * @param $op
     * @return array
     */
    private function formatFilterOp($filter, $op)
    {
        $filter = json_decode($filter, true);
        $op = json_decode($op, true);
        if (array_key_exists('group_id', $filter)) {
            if ($filter['group_id']) {
                $filter['group_id'] = Group::getRelationIds($filter['group_id']);
                $op['group_id'] = 'in';
            } else {
                $filter['group_id'] = 0;
                $op['group_id'] = '=';
            }
        }
        if (array_key_exists('state', $filter)) {
            if ($filter['state'] == -1) {
                $filter['fund_user.id'] = 0;
                $op['fund_user.id'] = 'IS NULL';
            } else {
                $filter['fund_user.status'] = $filter['state'];
                $op['fund_user.status'] = '=';
            }
            unset($filter['state'], $op['state']);
        }

        return [json_encode($filter), json_encode($op)];
    }

    /**
     * 删除
     */
    public function del($ids = null)
    {
        $ids = $ids ? $ids : $this->request->post("ids");
        if (! $activityId = $this->request->request('activity_id')) {
            $this->error(__('活动ID不存在'));
        }
        $row = $this->model::get(['activity_id' => $activityId, 'member_id' => $ids]);
        if (! $row) {
            $this->error(__('No Results were found'));
        }

        parent::del($row->id);
    }

    /**
     * 批量更新
     */
    public function multi($ids = "")
    {
        $ids = $ids ? $ids : $this->request->post("ids");
        if (! $activityId = $this->request->get('activity_id')) {
            $this->error(__('活动ID不能为空'));
        }
        if ($ids) {
            if ($this->request->has('params')) {
                parse_str($this->request->post("params"), $values);
                $values = $this->auth->isSuperAdmin() ? $values : array_intersect_key($values,
                    array_flip(is_array($this->multiFields) ? $this->multiFields : explode(',', $this->multiFields)));
                if ($values) {
                    $adminIds = $this->getDataLimitAdminIds();
                    if (is_array($adminIds)) {
                        $this->model->where($this->dataLimitField, 'in', $adminIds);
                    }
                    $count = 0;
                    Db::startTrans();
                    try {
                        if (isset($values['state']) && $values['state'] == -1) {  // 激活
                            $list = (new Member())->alias('A')
                                ->field('A.*')
                                ->join([FundUser::getTableName() => 'B'],
                                    'B.member_id=A.id and B.activity_id=' . $activityId . ' and B.deleted_at is null',
                                    'LEFT')
                                ->where('A.id', 'in', $ids)
                                ->where('B.id is null')
                                ->where('A.deleted_at is null')->select();
                            foreach ($list as $item) {
                                $memberId = $item['id'];
                                if (! FundUser::get(['activity_id' => $activityId, 'member_id' => $memberId])) {
                                    Db::transaction(function () use ($activityId, $memberId) {
                                        Norepeat::tryAddData('fund_user:init',
                                            $activityId . ':' . $memberId . ':' . date('ymdHi'));
                                        FundUser::create([
                                            'activity_id' => $activityId,
                                            'member_id'   => $memberId,
                                            'status'      => FundUser::STATUS_NORMAL
                                        ]);
                                    });
                                    $count++;
                                }
                            }
                        } else {
                            $list = $this->model->where(['activity_id' => $activityId])
                                ->where('member_id', 'in', $ids)->select();
                            foreach ($list as $index => $item) {
                                $count += $item->allowField(true)->isUpdate(true)->save($values);
                            }
                        }
                        Db::commit();
                    } catch (PDOException $e) {
                        Db::rollback();
                        $this->error($e->getMessage());
                    } catch (Exception $e) {
                        Db::rollback();
                        $this->error($e->getMessage());
                    }
                    if ($count) {
                        $this->success();
                    } else {
                        $this->error(__('No rows were updated'));
                    }
                } else {
                    $this->error(__('You have no permission'));
                }
            }
        }
        $this->error(__('Parameter %s can not be empty', 'ids'));
    }

    // 处理礼币
    public function handleAmount()
    {
        // 超时、超内存设置
        ini_set('memory_limit', '1024M');
        ini_set('max_execution_time', '0');

        $activityId = $this->request->get('activity_id');
        $initAmount = $this->request->post('init_amount');
        $changeAmount = $this->request->post('change_amount');
        if (! $initAmount && ! $changeAmount) {
            $this->error(__('礼币数量不能都为0'));
        }

        // 重载查询条件
        $search = $this->request->post('search');
        $ids = $this->request->post('ids');
        $filter = $this->request->post('filter');
        $op = $this->request->post('op');
        list($filter, $op) = $this->formatFilterOp($filter, $op);
        $whereIds = $ids === 'all' ? '1=1' : ['id' => ['in', explode(',', $ids)]];
        $this->request->get(['search' => $search, 'ids' => $ids, 'filter' => $filter, 'op' => $op]);

        // 通用查询条件
        $this->model = new Member();
        list($where, $sort, $order, $offset, $limit) = $this->buildparams();

        $counter = [];

        // 查询数据
        $this->model
            ->where($where)
            ->where($whereIds)
            ->chunk(100, function ($items) use (&$counter, $activityId, $initAmount, $changeAmount) {
                foreach ($items as $item) {
                    $memberId = $item->id;
                    if (! $fundUser = FundUser::get(['activity_id' => $activityId, 'member_id' => $memberId])) {
                        $fundUser = Db::transaction(function () use ($activityId, $memberId) {
                            Norepeat::tryAddData('fund_user:init', $activityId . ':' . $memberId . ':' . date('ymdHi'));

                            return \addons\yungift\model\FundUser::create([
                                'activity_id' => $activityId,
                                'member_id'   => $memberId,
                                'status'      => FundUser::STATUS_NORMAL
                            ]);
                        });
                    }
                    if ($initAmount) {
                        if ($fundUser->amount_give) {
                            Super::counter($counter, '已发放过礼币，初始化礼币数量失败');
                        } else {
                            try {
                                FundUser::amountCounter($activityId, $memberId, FundRecord::ACTION_BATCH_INIT,
                                    abs($initAmount));
                                Super::counter($counter, '初始化礼币数量成功');
                            } catch (Exception $e) {
                                Super::counter($counter, '初始化礼币数量异常: ' . $e->getMessage());
                                break;
                            }
                        }
                    }
                    if ($changeAmount) {
                        try {
                            $absAmount = abs($changeAmount);
                            if ($changeAmount > 0) {
                                FundUser::amountCounter($activityId, $memberId, FundRecord::ACTION_BATCH_PLUS,
                                    $absAmount);
                                Super::counter($counter, '增减礼币数量成功');
                            } else {
                                if ($absAmount > $fundUser->amount_give) {
                                    Super::counter($counter, '减少礼币数量不能大于已发放礼币数量');
                                    continue;
                                }
                                FundUser::amountCounter($activityId, $memberId, FundRecord::ACTION_BATCH_MINUS,
                                    -$absAmount);
                                Super::counter($counter, '增减礼币数量成功');
                            }
                        } catch (Exception $e) {
                            Super::counter($counter, '增减礼币数量异常: ' . $e->getMessage());
                            break;
                        }
                    }
                }
            });

        // 导入结果
        $content = ['处理成功<br>'];
        foreach ($counter as $key => $value) {
            $hasError = false;
            if (! in_array($key, ['初始化礼币数量成功', '增减礼币数量成功', '增减礼币数量成功'])) {
                $hasError = true;
            }
            $cont = $key . '： ' . $value . '条';
            if ($hasError) {
                $cont = '<b style="color: yellow;">' . $cont . '</b>';
            }
            $content[] = $cont;
        }
        $content = implode('<br>', $content);
        $this->success($content);
    }

    /**
     * 增加礼币
     */
    public function plus()
    {
        if ($this->request->isPost()) {
            $params = $this->request->post("row/a");
            if ($params) {
                if (! $activityId = $this->request->get('activity_id')) {
                    $this->error(__('活动ID不能为空'));
                }
                if ($params['amount'] < 0) {
                    $this->error(__('不能为负值'));
                }
                try {
                    FundUser::amountCounter($activityId, $params['member_id'], FundRecord::ACTION_MANUAL_PLUS,
                        abs($params['amount']));
                } catch (Exception $e) {
                    $this->error($e->getMessage());
                }
                $this->success();
            }
            $this->error(__('Parameter %s can not be empty', ''));
        }

        return $this->view->fetch();
    }

    /**
     * 减少礼币
     */
    public function minus()
    {
        if ($this->request->isPost()) {
            $params = $this->request->post("row/a");
            if ($params) {
                if (! $activityId = $this->request->get('activity_id')) {
                    $this->error(__('活动ID不能为空'));
                }
                if ($params['amount'] < 0) {
                    $this->error(__('不能为负值'));
                }
                if (! $fundUser = FundUser::get(['activity_id' => $activityId, 'member_id' => $params['member_id']])) {
                    $this->error(__('礼币账户未开通'));
                }
                if ($params['amount'] > $fundUser->amount_give) {
                    $this->error(__('减少礼币数量不能大于已发放礼币数量'));
                }
                try {
                    FundUser::amountCounter($activityId, $params['member_id'], FundRecord::ACTION_MANUAL_MINUS,
                        -$params['amount']);
                } catch (Exception $e) {
                    $this->error($e->getMessage());
                }
                $this->success();
            }
            $this->error(__('Parameter %s can not be empty', ''));
        }

        return $this->view->fetch();
    }


    /**
     * 操作礼币账户
     */
    public function handle()
    {
        $params = $this->request->post();
        if ($params) {
            try {
                $memberId = $params['ids'];
                $action = $params['action'];
                parse_str($params['params'], $values);
                $activityId = $values['aid'];
                if (! Activity::get($activityId)) {
                    $this->error('活动不存在，无法激活礼币账户');
                }
                if ($action === 'init') {
                    if (FundUser::get(['activity_id' => $activityId, 'member_id' => $memberId])) {
                        $this->error('礼币账户已激活');
                    }
                    Db::transaction(function () use ($activityId, $memberId) {
                        Norepeat::tryAddData('fund_user:init', $activityId . ':' . $memberId . ':' . date('ymdHi'));
                        \addons\yungift\model\FundUser::create([
                            'activity_id' => $activityId,
                            'member_id'   => $memberId,
                            'status'      => FundUser::STATUS_NORMAL
                        ]);
                    });
                } else {
                    if (! $fundUser = FundUser::get(['activity_id' => $activityId, 'member_id' => $memberId])) {
                        $this->error('礼币账户未激活');
                    }
                    if ($action === 'open') {
                        $fundUser->status = FundUser::STATUS_NORMAL;
                        $fundUser->save();
                    } elseif ($action === 'close') {
                        $fundUser->status = FundUser::STATUS_HIDDEN;
                        $fundUser->save();
                    }
                }
            } catch (Exception $e) {
                $this->error($e->getMessage());
            }
            $this->success();
        }
        $this->error(__('Parameter %s can not be empty', ''));
    }

}
